package com.tools.cleanmaster.functionpage;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.ValueAnimator;
import com.tools.cleanmaster.R;
import com.tools.cleanmaster.utils.UiUtils;

public class BatteryStateView extends View {

    LinearGradient mWaveGradient;
    Bitmap result;
    Bitmap markResult;
    ValueAnimator animator;
    ValueAnimator animatorHeight;
    // 波浪画笔
    private Paint mPaint;
    private Paint mSecondPaint;
    private Paint mCirclePaint;
    private Paint mInnerCirclePaint;
    private Path mPath;
    private int mWaveLength = 200;
    private Path mSecondPath;
    // 波纹个数
    private int mWaveCount;
    private int mOffset;
    private int mSecondOffset;
    private int mCenterY = Integer.MAX_VALUE;
    // 屏幕高度
    private int mScreenHeight;
    //屏幕宽度
    private int mScreenWidth;
    private int percent = 1;
    private Paint percentPaint;
    private Paint mOuterCirclePaint;
    private Context mContext;
    private boolean isBatteryNormal = true;
    private int currentPercent = 0;


    public BatteryStateView(Context context) {
        super(context);
    }

    public BatteryStateView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public BatteryStateView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mPath = new Path();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mSecondPath = new Path();
        mSecondPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mSecondPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mWaveLength = UiUtils.dipToPx(context, mWaveLength);

        mCirclePaint = new Paint();
        mCirclePaint.setAntiAlias(true);
        mCirclePaint.setStyle(Paint.Style.FILL);
        mCirclePaint.setFilterBitmap(true);

        mInnerCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mInnerCirclePaint.setColor(ContextCompat.getColor(context, R.color.function_battery_inner_circle));
        mInnerCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mInnerCirclePaint.setStrokeWidth(UiUtils.dipToPx(context, 10));

        percentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        percentPaint.setColor(Color.WHITE);
        percentPaint.setStyle(Paint.Style.FILL);
        percentPaint.setTextSize(UiUtils.dipToPx(context, 53));

        mOuterCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mOuterCirclePaint.setColor(ContextCompat.getColor(context, R.color.function_battery_outer_circle));
        mOuterCirclePaint.setStyle(Paint.Style.STROKE);
        mOuterCirclePaint.setStrokeWidth(UiUtils.dipToPx(context, 14));

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mScreenHeight = h;
        mScreenWidth = w;
        // 加1.5：至少保证波纹有2个，至少2个才能实现平移效果
        mWaveCount = (int) Math.round(mScreenWidth / mWaveLength + 1.5);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawCircle(mScreenHeight / 2, mScreenHeight / 2, mScreenHeight / 2 - UiUtils.dipToPx(mContext, 20), mInnerCirclePaint);
        canvas.drawCircle(mScreenHeight / 2, mScreenHeight / 2, mScreenHeight / 2 - UiUtils.dipToPx(mContext, 20), mOuterCirclePaint);
        canvas.drawBitmap(createWaveBitmap(), 0, 0, null);

        //画中间百分比
        canvas.drawText(currentPercent + "%", (mScreenHeight - percentPaint.measureText(currentPercent + "%")) / 2, (mScreenHeight - percentPaint.descent() - percentPaint.ascent()) / 2, percentPaint);

    }

    private Bitmap createWaveBitmap() {
        if (result == null) {
            result = Bitmap.createBitmap(mScreenHeight, mScreenHeight, Bitmap.Config.ARGB_8888);
        }
        result.eraseColor(Color.argb(0, 0, 0, 0));
        Canvas mCanvas = new Canvas(result);

        mCirclePaint.setXfermode(null);
        mCirclePaint.setStrokeWidth(1);
        mCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mCanvas.drawCircle(mScreenHeight / 2, mScreenHeight / 2, mScreenHeight / 2 - UiUtils.dipToPx(mContext, 20), mCirclePaint);

        mCirclePaint.setStrokeWidth(1);
        mCirclePaint.setStyle(Paint.Style.FILL);
        mCirclePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        mCanvas.drawBitmap(createWaveMarkBitmap(), 0, 0, mCirclePaint);
        return result;
    }

    private Bitmap createWaveMarkBitmap() {
        if (markResult == null) {
            markResult = Bitmap.createBitmap(mScreenHeight, mScreenHeight, Bitmap.Config.ARGB_8888);
        }
        markResult.eraseColor(Color.argb(0, 0, 0, 0));
        Canvas mCanvas = new Canvas(markResult);
        mSecondPath.reset();
        mPath.reset();
        mSecondPath.moveTo(0, mCenterY);
        mPath.moveTo(0, mCenterY);
        for (int i = 0; i < mWaveCount; i++) {
            // 正弦曲线
            mSecondPath.quadTo((-mWaveLength * 3 / 4) + (i * mWaveLength) + mSecondOffset, mCenterY - (40 + 6 * i), (-mWaveLength / 2) + (i * mWaveLength) + mSecondOffset, mCenterY);
            mSecondPath.quadTo((-mWaveLength / 4) + (i * mWaveLength) + mSecondOffset, mCenterY + (40 + 6 * i), i * mWaveLength + mSecondOffset, mCenterY);
            mPath.quadTo((-mWaveLength * 3 / 4) + (i * mWaveLength) + mOffset, mCenterY + (40 + 6 * i), (-mWaveLength / 2) + (i * mWaveLength) + mOffset, mCenterY);
            mPath.quadTo((-mWaveLength / 4) + (i * mWaveLength) + mOffset, mCenterY - (40 + 6 * i), i * mWaveLength + mOffset, mCenterY);
        }
        mSecondPath.lineTo(mScreenWidth, mScreenHeight);
        mSecondPath.lineTo(0, mScreenHeight);
        mSecondPath.close();
        mSecondPaint.setColor(ContextCompat.getColor(mContext, isBatteryNormal ? R.color.function_battery_normal_wave : R.color.function_battery_over_wave));
        mCanvas.drawPath(mSecondPath, mSecondPaint);
        // 填充矩形
        mPath.lineTo(mScreenWidth, mScreenHeight);
        mPath.lineTo(0, mScreenHeight);
        mPath.close();
        if (mWaveGradient == null) {
            mWaveGradient = new LinearGradient(0, mScreenHeight / 2, 0, mScreenHeight,
                    ContextCompat.getColor(mContext, isBatteryNormal ? R.color.function_battery_normal_start : R.color.function_battery_over_start),
                    ContextCompat.getColor(mContext, isBatteryNormal ? R.color.function_battery_normal_end : R.color.function_battery_over_end),
                    Shader.TileMode.CLAMP);
        }
        mPaint.setShader(mWaveGradient);
        mCanvas.drawPath(mPath, mPaint);
        return markResult;
    }

    public void startScanBattery(int percent, boolean isBatteryNormal, final Animator.AnimatorListener animatorListener) {
        this.isBatteryNormal = isBatteryNormal;
        this.percent = percent;
        mWaveGradient = null;
        mPaint.setShader(null);
        animator = ValueAnimator.ofInt(0, mWaveLength);
        animator.setDuration(5000);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setRepeatMode(ValueAnimator.REVERSE);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mOffset = (Integer) animation.getAnimatedValue();
                mSecondOffset = mWaveLength - mOffset;
                postInvalidate();
            }
        });
        animator.start();
        // 电量水波纹上升，开始动画前必须要等到拿到高度才ok
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startWaveRise(animatorListener);
            }
        }, 300);
    }

    private void startWaveRise(Animator.AnimatorListener animatorListener) {
        final int validHeight = mScreenHeight - UiUtils.dipToPx(mContext, 19);
        animatorHeight = ValueAnimator.ofInt(0, percent);
        animatorHeight.setDuration(6000 * percent / 100);
        animatorHeight.setInterpolator(new DecelerateInterpolator());
        animatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                currentPercent = (Integer) animation.getAnimatedValue();
                mCenterY = mScreenHeight - validHeight * currentPercent / 100;
                postInvalidate();
            }
        });
        animatorHeight.addListener(animatorListener);
        animatorHeight.start();
    }

    /**
     * 当view不再使用时要即使取消动画，销毁对象
     */
    public void onDestroyView() {
        if (animator != null) {
            animator.cancel();
        }
        if (animatorHeight != null) {
            animatorHeight.cancel();
        }
        result = null;
        markResult = null;
    }
}
